use crate::resp::error::RespError;
use crate::resp::{RespDecode, RespEncode, CRLF_LEN};
use bytes::BytesMut;
use std::ops::Deref;

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct SimpleString(pub(crate) String);

impl Deref for SimpleString {
    type Target = String;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl SimpleString {
    pub fn new(s: impl Into<String>) -> Self {
        SimpleString(s.into())
    }
}

impl RespEncode for SimpleString {
    fn encode(self) -> Vec<u8> {
        format!("+{}\r\n", self.0).into_bytes()
    }
}

impl RespDecode for SimpleString {
    const PREFIX: &'static str = "+";

    fn decode(buf: &mut BytesMut) -> Result<SimpleString, RespError> {
        let end = crate::resp::decode::extract_simple_frame_data(buf, Self::PREFIX)?;
        //split the buf
        let data = buf.split_to(end + 2);
        let v = data[1..end].to_vec();
        let s = String::from_utf8_lossy(&v);
        Ok(SimpleString(s.to_string()))
    }

    fn expect_length(buf: &[u8]) -> Result<usize, RespError> {
        let end = crate::resp::decode::extract_simple_frame_data(buf, Self::PREFIX)?;
        Ok(end + CRLF_LEN)
    }
}
